package com.nexus.core.utils;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 属性配置工具类
 *
 * @Date 2025/9/22 00:36
 * @Author luzhengning
 **/
public class PropertiesUtils {

    /**
     * 主配置文件名称
     *
     * @Date 2025/9/22 00:41
     * @Author luzhengning
     **/
    public final static String ApplicationProperties = "application.properties";

    /**
     * Resource转配置文件
     *
     * @Date 2025/9/22 00:34
     * @Author luzhengning
     **/
    public static Properties loadProperties(Resource resource) {
        Properties props = new Properties();
        try (InputStream input = resource.getInputStream()) {
            props.load(input);
            return props;
        } catch (IOException e) {
            throw new RuntimeException("Failed to load properties from " + resource.getFilename(), e);
        }
    }

    /**
     * 获取所有resource目录下指定的文件
     *
     * @Date 2025/9/21 23:36
     * @Author luzhengning
     **/
    public static Resource getResourceFiles(String resourceName) {
        // 获取当前类的包路径，并转换为资源路径
        String resourcePattern = "classpath*:" + resourceName;
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            Resource[] resources = resolver.getResources(resourcePattern);


            for (Resource resource : resources) {
                if (resource.exists() && resource.isReadable()) {
                    return resource;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    /**
     * 获取指定配置文件中的属性值
     *
     * @Date 2025/9/22 00:40
     * @Author luzhengning
     **/
    public static Object getProperties(String resourceName, String key) {
        Resource resourceFiles = getResourceFiles(resourceName);
        return loadProperties(resourceFiles).get(key);
    }

    /**
     * 获取当前配置环境
     * 读取spring.profiles.active
     * @Date 2025/9/22 00:43
     * @Author luzhengning
     **/
    public static String getEnv() {
        return getProperties(ApplicationProperties,"spring.profiles.active").toString();
    }

    /**
     * 根据当前环境获取指定配置文件对应的配置信息
     * @Date 2025/9/22 00:49
     * @Author luzhengning
     **/
    public static Properties convertReourceOnEnv(String resourceName) {
        String[] nameSplit = resourceName.split("\\.");
        String loadConfigName = nameSplit[0] + "-" + getEnv() + "." + nameSplit[1];
        //获取对应的配置文件
        Resource loadConfigResource = PropertiesUtils.getResourceFiles(loadConfigName);
        // 实现自定义属性加载逻辑
        if (loadConfigResource != null) {
            Properties properties = PropertiesUtils.loadProperties(loadConfigResource);
            return properties;
        }
        return null;
    }

    /**
     * 检查配置文件名是否匹配模式
     *
     * @param baseFileName    基础文件名，如 "nacos.properties"
     * @param fileNameToCheck 要检查的文件名，如 "nacos-dev.properties"
     * @return 是否匹配
     * @Date 2025/9/22 00:56
     * @Author luzhengning
     */
    public static boolean isFileNameMatch(String baseFileName, String fileNameToCheck) {
        // 将基础文件名分解为名称和扩展名
        int dotIndex = baseFileName.lastIndexOf('.');
        String baseName = (dotIndex > 0) ? baseFileName.substring(0, dotIndex) : baseFileName;
        String extension = (dotIndex > 0 && dotIndex < baseFileName.length() - 1)
                ? baseFileName.substring(dotIndex) : "";

        // 构建正则表达式模式
        String patternStr = Pattern.quote(baseName) + "-.*" + Pattern.quote(extension);
        Pattern pattern = Pattern.compile(patternStr);

        // 检查是否匹配
        Matcher matcher = pattern.matcher(fileNameToCheck);
        return matcher.matches();
    }

    /**
     * 删除重复的nacos的配置项，如果其它地方的配置项与自己的nacos配置项一致，就删除自己的配置，以其它地方的配置为主
     *
     * @Date 2025/9/18 03:49
     * @Author luzhengning
     **/
    public static void removeRepeatConfig(String templatePropertiesName,Properties config) {
        try {
            Set<String> localPropertyKeys = new HashSet<>();
            Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath*:*.properties");
            if (ObjectUtils.isEmpty(resources) || resources.length == 0) {
                return;
            }
            for (Resource resource : resources) {
                if (isFileNameMatch(templatePropertiesName, resource.getFilename())) {
                    continue;
                }
                try (InputStream inputStream = resource.getInputStream()) {
                    Properties props = new Properties();
                    props.load(inputStream);
                    // 收集所有本地配置键
                    localPropertyKeys.addAll(props.stringPropertyNames());
                }
            }
            // 移除所有重复的键
            localPropertyKeys.forEach(config::remove);
        } catch (IOException e) {
            // 使用更具体的异常类型
            throw new RuntimeException("检查并删除重复的Nacos配置时出错", e);
        }
    }

}
